package dq.study.concurrent.threadpool;

import javax.xml.transform.Result;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * jdk1.5 future target异步响应
 * guava ListenableFuture
 * jdk 1.8
 *
 * @author dongqun
 * @date 2020/7/16 10:11
 */
public class FutureTry {

    private static List<MyTask> tasks = new ArrayList<>();

    private static List<CompletableFuture> futures = new ArrayList<>();

    private static MyTask task1, task2, task3;
    private  static ExecutorService executor = Executors.newCachedThreadPool();

    static {
        task1 = new MyTask("task1", 100, true);
        task2 = new MyTask("task2", 30, true);
        task3 = new MyTask("task3", 10, false);
    }

    /**
     * evn: 多任务并发执行，其中有一个任务失败则全部失败
     */
    public static void main(String[] args) {
        task1.addListener(resutl -> {
            if (!resutl) {
                System.out.println("task1 end");
                onClose();
            }
        });
        tasks.add(task1);
        task2.addListener(resutl -> {
            if (!resutl) {
                System.out.println("task2 end");
                onClose();
            }
        });
        tasks.add(task2);
        task3.addListener(resutl -> {
            if (!resutl) {
                System.out.println("task3 end");
                onClose();
            }
        });
        tasks.add(task3);

        for (MyTask task : tasks) {
//            CompletableFuture<Object> future = CompletableFuture.supplyAsync(task::call, executor);
//                    .thenApply(FutureTry::cancel);
            futures.add(CompletableFuture.supplyAsync(task::call, executor));
        }

    }


    private static void onClose() {
        // 这里cancel都返回TRUE了但是实际上并没有停掉另外几个线程，why？
        for (CompletableFuture f : futures) {
            System.out.println(f.cancel(true));
        }
        executor.shutdown();
    }


    static class MyTask {
        private String name;
        private Integer time;
        private Boolean result;
        private ResultListener listener;

        public MyTask(String name, Integer time, Boolean result) {
            this.name = name;
            this.time = time * 1000;
            this.result = result;
        }

        public boolean call() {
            try {
                System.out.println(name + "任务开始");
                Thread.sleep(time);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(name + "任务结束");
            listener.onFinish(result);
            return result;
        }

        public void addListener(ResultListener resultListener) {
            this.listener = resultListener;
        }


    }


    private interface ResultListener {
        void onFinish(boolean resutl);
    }


}
